L.Edit = L.Edit || {}

L.Edit.Sector = L.Edit.SimpleShape.extend({
    options: {
        moveIcon: new L.DivIcon({
            iconSize: new L.Point(8, 8),
            className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move'
        }),
        startRadiusIcon: new L.DivIcon({
            iconSize: new L.Point(8, 8),
            className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
        }),
        endRadiusIcon: new L.DivIcon({
            iconSize: new L.Point(8, 8),
            className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
        }),
        startAngleIcon: new L.DivIcon({
            iconSize: new L.Point(8, 8),
            className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
        }),
        endAngleIcon: new L.DivIcon({
            iconSize: new L.Point(8, 8),
            className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
        })
    },

    _initMarkers: function () {
        if (!this._markerGroup) {
            this._markerGroup = new L.LayerGroup()
        }
        this._resizeMarkers = []

        // Create center marker
        this._createMoveMarker()

        // Create radius marker
        this._createStartRadiusMarker()
        this._createEndRadiusMarker()

        // Create angle Marker();
        this._createStartAngleMarker()
        this._createEndAngleMarker()

    },

    _createMoveMarker:function () {
        var center = this._shape.getLatLng();
        this._moveMarker = this._createMarker(center, this.options.moveIcon)
    },

    _createStartRadiusMarker:function () {
        var center = this._shape.getLatLng()

        var start = this._shape.getStartBearing()

        var end = this._shape.getEndBearing()

        var bearing = (start + end) / 2

        if (start > end) {
            if (bearing < 180) bearing = 180 + bearing;
            else bearing = bearing - 180;
        }

        var point = this._shape.computeDestinationPoint(
            center,
            this._shape.getStartRadius(),
            bearing
        )

        this._startRadiusMarker = this._createMarker(point, this.options.startRadiusIcon)
    },

    _createEndRadiusMarker: function () {
        var center = this._shape.getLatLng()

        var start = this._shape.getStartBearing()

        var end = this._shape.getEndBearing()

        var bearing = (start + end) / 2

        if (start > end) {
            if (bearing < 180) bearing = 180 + bearing;
            else bearing = bearing - 180;
        }

        var point = this._shape.computeDestinationPoint(
            center,
            this._shape.getEndRadius(),
            bearing
        )

        this._endRadiusMarker = this._createMarker(point, this.options.endRadiusIcon)
    },

    _createStartAngleMarker: function () {
        var center = this._shape.getLatLng()

        var point = this._shape.computeDestinationPoint(
            center,
            (this._shape.getStartRadius() + this._shape.getEndRadius())/2,
            this._shape.getStartBearing()
        )

        this._startAngleMarker = this._createMarker(point, this.options.startAngleIcon)
    },

    _createEndAngleMarker: function () {
        var center = this._shape.getLatLng()

        var point = this._shape.computeDestinationPoint(
            center,
            (this._shape.getStartRadius() + this._shape.getEndRadius())/2,
            this._shape.getEndBearing()
        )

        this._endAngleMarker = this._createMarker(point, this.options.endAngleIcon)
    },

    _onMarkerDragStart:function (e) {
        L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e)
        this._currentMarker = e.target
    },

    _onMarkerDrag:function (e) {
        var marker = e.target,
            latlng = marker.getLatLng()

        if (marker === this._moveMarker) {
            this._move(latlng)
        } else if (marker === this._startRadiusMarker) {
            this._resizeStartRadius(latlng)
        } else if (marker === this._endRadiusMarker) {
            this._resizeEndRadius(latlng)
        } else if (marker === this._startAngleMarker) {
            this._resizeStartAngle(latlng)
        } else if (marker === this._endAngleMarker) {
            this._resizeEndAngle(latlng)
        }

        this._shape.redraw()
    },

    _move:function (latlng) {
        this._shape.setLatLng(latlng)

        // Move the resize marker
        this._repositionStartRadiusMarker()
        this._repositionEndRadiusMarker()
        this._repositionStartAngleMarker()
        this._repositionEndAngleMarker()
    },

    _resizeStartRadius:function (latlng) {
        var innerRadius = this._shape.getLatLng().distanceTo(latlng)
        this._shape.setStartRadius(innerRadius)

        this._repositionStartAngleMarker()
        this._repositionEndAngleMarker()
        this._repositionStartRadiusMarker()
        this._repositionEndRadiusMarker()
    },

    _resizeEndRadius:function (latlng) {
        var outerRadius = this._shape.getLatLng().distanceTo(latlng)
        this._shape.setEndRadius(outerRadius)

        this._repositionStartAngleMarker()
        this._repositionEndAngleMarker()
        this._repositionStartRadiusMarker()
        this._repositionEndRadiusMarker()
    },

    _resizeStartAngle:function (latlng) {
        var moveLatLng = this._shape.getLatLng()

        var pc = this._map.project(moveLatLng)
        var ph = this._map.project(latlng)
        var v = [ph.x - pc.x, ph.y - pc.y]

        var newB = Math.atan2(v[0], -v[1]) * 180 / Math.PI

        this._shape.setStartAngle(this.getAngle(newB));

        this._repositionStartRadiusMarker()
        this._repositionEndRadiusMarker()
        this._repositionStartAngleMarker()
        this._repositionEndAngleMarker()
    },

    _resizeEndAngle:function (latlng) {
        var moveLatLng = this._shape.getLatLng(),
            pc = this._map.project(moveLatLng),
            ph = this._map.project(latlng),
            v = [ph.x - pc.x, ph.y - pc.y],

            newB = Math.atan2(v[0], -v[1]) * 180 / Math.PI

        this._shape.setEndAngle(this.getAngle(newB));

        this._repositionStartRadiusMarker()
        this._repositionEndRadiusMarker()
        this._repositionStartAngleMarker()
        this._repositionEndAngleMarker()
    },

    _repositionStartRadiusMarker:function () {
        var center = this._shape.getLatLng()

        var start = this._shape.getStartBearing()

        var end = this._shape.getEndBearing()

        var bearing = (start + end) / 2

        if (start > end) {
            if (bearing < 180) bearing = 180 + bearing;
            else bearing = bearing - 180;
        }

        var point = this._shape.computeDestinationPoint(
            center,
            this._shape.getStartRadius(),
            bearing
        )

        this._startRadiusMarker.setLatLng(point)
    },

    _repositionEndRadiusMarker:function  () {
        var center = this._shape.getLatLng()

        var start = this._shape.getStartBearing()

        var end = this._shape.getEndBearing()

        var bearing = (start + end) / 2

        if (start > end) {
            if (bearing < 180) bearing = 180 + bearing;
            else bearing = bearing - 180;
        }

        var point = this._shape.computeDestinationPoint(
            center,
            this._shape.getEndRadius(),
            bearing
        )

        this._endRadiusMarker.setLatLng(point)
    },

    _repositionStartAngleMarker:function  () {
        var center = this._shape.getLatLng()

        var point = this._shape.computeDestinationPoint(
            center,
            (this._shape.getStartRadius() + this._shape.getEndRadius())/2,
            this._shape.getStartBearing()
        )
        this._startAngleMarker.setLatLng(point)
    },

    _repositionEndAngleMarker:function  () {
        var center = this._shape.getLatLng()

        var point = this._shape.computeDestinationPoint(
            center,
            (this._shape.getStartRadius() + this._shape.getEndRadius())/2,
            this._shape.getEndBearing()
        )
        this._endAngleMarker.setLatLng(point)
    },

    getAngle: function (angle) {
        angle = Number(angle);
        if (angle >= 90 && angle <= 180) {
            return Math.abs(angle) - 90;
        } else {
            return 270 + angle;
        }
    }

})

L.Sector.addInitHook(function () {
    if (L.Edit.Sector) {
        this.editing = new L.Edit.Sector(this)

        if (this.options.editable) {
            this.editing.enable()
        }
    }

    this.on('add', function () {
        if (this.editing && this.editing.enabled()) {
            this.editing.addHooks()
        }
    })

    this.on('remove', function () {
        if (this.editing && this.editing.enabled()) {
            this.editing.removeHooks()
        }
    })
})
